﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Settlements.Hideout
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Settlements
{
  public class Hideout : SettlementComponent, ISpottable
  {
    [SaveableField(200)]
    private CampaignTime _nextPossibleAttackTime;
    [SaveableField(201)]
    private bool _isSpotted;

    internal static void AutoGeneratedStaticCollectObjectsHideout(
      object o,
      List<object> collectedObjects)
    {
      ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      CampaignTime.AutoGeneratedStaticCollectObjectsCampaignTime((object) this._nextPossibleAttackTime, collectedObjects);
    }

    internal static object AutoGeneratedGetMemberValue_nextPossibleAttackTime(object o)
    {
      return (object) ((Hideout) o)._nextPossibleAttackTime;
    }

    internal static object AutoGeneratedGetMemberValue_isSpotted(object o)
    {
      return (object) ((Hideout) o)._isSpotted;
    }

    public CampaignTime NextPossibleAttackTime => this._nextPossibleAttackTime;

    public static MBReadOnlyList<Hideout> All => Campaign.Current.AllHideouts;

    public void UpdateNextPossibleAttackTime()
    {
      this._nextPossibleAttackTime = CampaignTime.Now + CampaignTime.Hours(12f);
    }

    public bool IsInfested
    {
      get
      {
        return this.Owner.Settlement.Parties.CountQ<MobileParty>((Func<MobileParty, bool>) (x => x.IsBandit)) >= Campaign.Current.Models.BanditDensityModel.NumberOfMinimumBanditPartiesInAHideoutToInfestIt;
      }
    }

    public IEnumerable<PartyBase> GetDefenderParties(MapEvent.BattleTypes battleType)
    {
      Hideout hideout = this;
      yield return hideout.Settlement.Party;
      foreach (MobileParty party in (List<MobileParty>) hideout.Settlement.Parties)
      {
        if (party.IsBandit || party.IsBanditBossParty)
          yield return party.Party;
      }
    }

    public PartyBase GetNextDefenderParty(ref int partyIndex, MapEvent.BattleTypes battleType)
    {
      ++partyIndex;
      if (partyIndex == 0)
        return this.Settlement.Party;
      for (int index = partyIndex - 1; index < this.Settlement.Parties.Count; ++index)
      {
        MobileParty party = this.Settlement.Parties[index];
        if (party.IsBandit || party.IsBanditBossParty)
        {
          partyIndex = index + 1;
          return party.Party;
        }
      }
      return (PartyBase) null;
    }

    public string SceneName { get; private set; }

    public IFaction MapFaction
    {
      get
      {
        foreach (MobileParty party in (List<MobileParty>) this.Settlement.Parties)
        {
          if (party.IsBandit)
            return (IFaction) party.ActualClan;
        }
        foreach (Clan mapFaction in (List<Clan>) Clan.All)
        {
          if (mapFaction.IsBanditFaction)
            return (IFaction) mapFaction;
        }
        return (IFaction) null;
      }
    }

    public bool IsSpotted
    {
      get => this._isSpotted;
      set => this._isSpotted = value;
    }

    public void SetScene(string sceneName) => this.SceneName = sceneName;

    public Hideout() => this.IsSpotted = false;

    public override void OnPartyEntered(MobileParty mobileParty)
    {
      base.OnPartyEntered(mobileParty);
      this.UpdateOwnership();
      if (!mobileParty.MapFaction.IsBanditFaction)
        return;
      mobileParty.BanditPartyComponent.SetHomeHideout(this.Owner.Settlement.Hideout);
    }

    public override void OnPartyLeft(MobileParty mobileParty)
    {
      this.UpdateOwnership();
      if (this.Owner.Settlement.Parties.Count != 0)
        return;
      this.OnHideoutIsEmpty();
    }

    public override void OnRelatedPartyRemoved(MobileParty mobileParty)
    {
      if (this.Owner.Settlement.Parties.Count != 0)
        return;
      this.OnHideoutIsEmpty();
    }

    private void OnHideoutIsEmpty()
    {
      this.IsSpotted = false;
      this.Owner.Settlement.IsVisible = false;
      CampaignEventDispatcher.Instance.OnHideoutDeactivated(this.Settlement);
    }

    public override void OnInit() => this.Owner.Settlement.IsVisible = false;

    public override void Deserialize(MBObjectManager objectManager, XmlNode node)
    {
      this.BackgroundCropPosition = float.Parse(node.Attributes["background_crop_position"].Value);
      this.BackgroundMeshName = node.Attributes["background_mesh"].Value;
      this.WaitMeshName = node.Attributes["wait_mesh"].Value;
      base.Deserialize(objectManager, node);
      if (node.Attributes["scene_name"] == null)
        return;
      this.SceneName = node.Attributes["scene_name"].InnerText;
    }

    private void UpdateOwnership()
    {
      if (this.Owner.MemberRoster.Count != 0 && !this.Owner.Settlement.Parties.All<MobileParty>((Func<MobileParty, bool>) (x => x.Party.Owner != this.Owner.Owner)))
        return;
      this.Owner.Settlement.Party.SetVisualAsDirty();
    }

    protected override void OnInventoryUpdated(ItemRosterElement item, int count)
    {
    }
  }
}
